package com.yonyou.crm.sact.schedule.service;

import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yonyou.crm.common.biz.service.BaseBizServiceImpl;
import com.yonyou.crm.common.enumeration.service.EnumBizServiceImpl;
import com.yonyou.crm.common.exception.CrmBusinessException;
import com.yonyou.crm.common.field.handler.FieldRelationHandler;
import com.yonyou.crm.common.field.relation.FieldRelation;
import com.yonyou.crm.common.field.relation.RefFieldRelation;
import com.yonyou.crm.cum.contact.entity.ContactVO;
import com.yonyou.crm.cum.customer.entity.CustomerVO;
import com.yonyou.crm.sact.schedule.entity.ScheduleTaskcardVO;
import com.yonyou.crm.sact.schedule.entity.ScheduleTypeEnum;
import com.yonyou.crm.sact.schedule.entity.ScheduleVO;
import com.yonyou.crm.sact.taskcard.entity.SactTaskcardVO;
import com.yonyou.crm.sact.taskcard.service.SactTaskcardBizServiceImpl;
import com.yonyou.crm.sact.visit.entity.VisitsVO;
import com.yonyou.crm.sact.visitrule.entity.VisitruleTaskcardVO;
import com.yonyou.crm.sact.visitrule.entity.VisitruleVO;
import com.yonyou.crm.sact.visitrule.service.VisitruleBizServiceImpl;
import com.yonyou.crm.sprc.lead.entity.LeadVO;
import com.yonyou.crm.sprc.opportunity.entity.OpportunityVO;
import com.yonyou.crm.sprc.opportunity.service.OpportunityBizServiceImpl;
import com.yonyou.crm.sys.modules.entity.MtObjTypeEnum;
import com.yonyou.crm.sys.org.service.SysOrgBizServiceImpl;
import com.yonyou.crm.sys.user.entity.UserVO;
import com.yonyou.crm.sys.user.service.UserBizServiceImpl;
import com.yonyou.iuap.context.InvocationInfoProxy;

@Service
public class ScheduleBizServiceImpl  extends BaseBizServiceImpl<ScheduleVO>  {
	
	@Autowired
	private SysOrgBizServiceImpl orgService;
	@Autowired
	private EnumBizServiceImpl enumService;
	@Autowired
	private VisitruleBizServiceImpl visitruleService;
	@Autowired
	private SactTaskcardBizServiceImpl tcService;
	@Autowired
	private OpportunityBizServiceImpl opportunityService;
	@Autowired
	private ScheduleTaskcardBizServiceImpl stService;
	@Autowired
	private UserBizServiceImpl userService;
	
	public List<ScheduleVO> getScheduleList(Map<String, Object> paraMap) {
		
		paraMap.put("ownerUserId", new Long(InvocationInfoProxy.getParameter("id")));
		
		List<ScheduleVO> scheduleList = dao.selectVoList(ScheduleVO.class, "getScheduleList", paraMap);
		
		transSchedule(scheduleList);
		
		return scheduleList;
	}
	
	public List<String> getScheduleDateList(Map<String, Object> paraMap) {
		paraMap.put("ownerUserId", new Long(InvocationInfoProxy.getParameter("id")));
		List<String> res = new ArrayList<String>();
		List<ScheduleVO> scheduleList = dao.selectVoList(ScheduleVO.class, "getScheduleDateList", paraMap);
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		String dateStr = "";
		for(int i = 0; i < scheduleList.size(); i++){
			ScheduleVO visit = scheduleList.get(i);
			Date date = visit.getDate();
			dateStr = formatter.format(date);
		    res.add(dateStr);
		}
		
		return res;
	}

	/**
	 * 日程信息转化
	 * @param scheduleList
	 * @return
	 */
	private List<ScheduleVO> transSchedule(List<ScheduleVO> scheduleList) {
		
		int listSize = scheduleList.size();
		if (scheduleList != null && listSize > 0) {
			
			List<FieldRelation<ScheduleVO>> relations = new ArrayList<FieldRelation<ScheduleVO>>();
			relations.add(new RefFieldRelation<ScheduleVO>(ScheduleVO.class, "orgId", new String[]{"orgName"}, orgService, "selectFieldsByIds"));
			new FieldRelationHandler<ScheduleVO>().handler(scheduleList, relations);
			
			List<UserVO> userList = new ArrayList<>();
			for(int i = 0; i < listSize; i++) {
				ScheduleVO schedule = scheduleList.get(i);
				//UserVO user = schedule.getOwnerInfo();
				//userList.add(user);
				//因为user mapper的idGetUser返回类型由UserVO改为UserDO所引起的修改
				//（取消在mapper里使用association,改为调用user的getDetail方法）
				Long userId = schedule.getOwnerUserId();
				UserVO user = userService.getDetail(userId);
				schedule.setOwnerInfo(user);
			}
			/*
			if ((userList != null) && (userList.size() > 0)) {
				userList = transUser(userList);
			}
			*/
			//拜访规则
			List<VisitruleVO> visitRuleList = getVisitRuleList(InvocationInfoProxy.getParameter("orgid"));
			String cumFuncName = getCumFuncName(visitRuleList);
			
			//所有任务卡
			List<SactTaskcardVO> allTList = tcService.getRefList(null);

			for(int i = 0; i < listSize; i++) {
				ScheduleVO schedule = scheduleList.get(i);
				transScheduleVO(schedule, cumFuncName, visitRuleList, userList, allTList);
			}
		}

		return scheduleList;
	}
	
	/**
	 * 转化日程信息
	 * @param schedule
	 * @param cumFuncName
	 * @param visitRuleList
	 * @param userList
	 * @param allTList
	 */
	private void transScheduleVO(ScheduleVO schedule, String cumFuncName, List<VisitruleVO> visitRuleList, List<UserVO> userList, List<SactTaskcardVO> allTList) {
		Integer scheduleStatus = checkScheduleStatus(schedule);
		Map<String, Object> statusParam = new HashMap<String, Object>();
		statusParam.put("status", scheduleStatus);
		statusParam.put("scheduleId", schedule.getId());
		dao.updateSql(VisitsVO.class, "updateScheduleStatus", statusParam);
		schedule.setStatus(checkScheduleStatus(schedule));
		//翻译负责人信息
		UserVO user = schedule.getOwnerInfo();
		for(int j = 0; j < userList.size(); j++) {
			UserVO userInfo = userList.get(j);
			if (user.getId() == userInfo.getId()) {
				user = userInfo;
			}
		}
		schedule.setOwnerInfo(user);
		
		transTaskCard(schedule, cumFuncName, visitRuleList, allTList);
		
		//TODO 判断任务卡是否已经填写
		VisitruleVO visitRule = schedule.getVisitRule();
		if(visitRule != null){
			Long scheduleId = schedule.getId();
			List<VisitruleTaskcardVO> vrtcList = visitRule.getTaskcardList();
			if(vrtcList != null && vrtcList.size() > 0){
				for(VisitruleTaskcardVO vrtc : vrtcList){
					String writeFlag = validateTaskcard(scheduleId, vrtc);
					vrtc.setWriteFlag(writeFlag);
				}
			}
		}
	}
	
	/**
	 * 转化任务卡信息
	 * @param schedule
	 * @param cumFuncName
	 * @param visitRuleList
	 * @param allTList
	 */
	private void transTaskCard(ScheduleVO schedule, String cumFuncName, List<VisitruleVO> visitRuleList, List<SactTaskcardVO> allTList){
		int visitRuleSize = visitRuleList.size();
		if (visitRuleSize > 0) {
			//获取任务卡信息
			CustomerVO customer = schedule.getCumInfo();
			int cumValue = getValueByMethodName(customer, cumFuncName);
			if (cumValue != -1) {
				for (int j = 0; j < visitRuleSize; j++) {
					VisitruleVO visitRule = visitRuleList.get(j);
					List<VisitruleTaskcardVO> checkedList = visitRule.getTaskcardList();
					Iterator<SactTaskcardVO> allIterator = allTList.iterator();
					while (allIterator.hasNext()) {
						SactTaskcardVO allVO = allIterator.next();
						for (VisitruleTaskcardVO checkedVO : checkedList) {
							if (allVO.getId().equals(checkedVO.getTaskcardId())) {
								//翻译选中的任务卡名称
								if(checkedVO.getMtObjId().equals(new Long("0"))){
									checkedVO.setTaskcardName(allVO.getName());
								}else{
									checkedVO.setTaskcardName(allVO.getMtBiztypeName());
								}
								checkedVO.setMtObjName(allVO.getMtObjName());
								checkedVO.setMtBiztypeName(allVO.getMtBiztypeName());
								//移除选中的任务卡
								allIterator.remove();
							}
						}
					}
					int visitRuleValue = visitRule.getCumEnumValue();
					if (cumValue == visitRuleValue) {
						schedule.setVisitRule(visitRule);
					}
				}
			}
		}
	}
	
	/**
	 * 获取拜访规则标识值的获取方法名
	 * @param visitRuleList
	 * @return
	 */
	private String getCumFuncName(List<VisitruleVO> visitRuleList) {
		String cumFuncName = "";
		int visitRuleSize = visitRuleList.size();
		if (visitRuleSize > 0) {
			long refIndex = getRefIndex();
			if (refIndex == 1) {
				cumFuncName = "getLevel";
			} else if (refIndex == 2) {
				cumFuncName = "getType";
			} else if (refIndex == 3) {
				cumFuncName = "getState";
			}
		}
		return cumFuncName;
	}
	
	/**
	 * 判断日程状态
	 * @param schedule
	 * @return
	 */
	public Integer checkScheduleStatus(ScheduleVO schedule){
		//判断日程状态
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("scheduleId", schedule.getId());
		List<ScheduleTaskcardVO> stList = stService.getList(param);
		int requiredStatus = 0;
		int notRequiredStatus = 0;
		List<ScheduleTaskcardVO> requiredStList = new ArrayList<ScheduleTaskcardVO>();
		List<ScheduleTaskcardVO> notRequiredStList = new ArrayList<ScheduleTaskcardVO>();
		if(stList != null && stList.size() > 0){
			for(ScheduleTaskcardVO st : stList){
				if(st.getRequired() == 1){
					requiredStList.add(st);
				}else{
					notRequiredStList.add(st);
				}
			}
		}
		if(requiredStList != null && requiredStList.size() > 0){
			for(ScheduleTaskcardVO st : requiredStList){
				if(st.getWrittenNum() != null && st.getWrittenNum() > 0){
					requiredStatus += 1;
				}
			}
		}
		if(notRequiredStList != null && notRequiredStList.size() > 0){
			for(ScheduleTaskcardVO st : notRequiredStList){
				if(st.getWrittenNum() != null && st.getWrittenNum() > 0){
					notRequiredStatus += 1;
				}
			}
		}
		if(requiredStatus == 0 && notRequiredStatus == 0){
			return 1;
		}else if(requiredStatus > 0 && requiredStatus < requiredStList.size()){
			return 2;
		}else if(notRequiredStatus > 0 && requiredStatus < requiredStList.size()){
			return 2;
		}else if(requiredStatus == requiredStList.size()){
			return 3;
		}
		return 1;
	}
	
	/**
	 * 验证任务卡是否进行填写
	 * @param vrtc
	 * @return
	 */
	private String validateTaskcard(Long scheduleId, VisitruleTaskcardVO vrtc){
		List<Map<String, Object>> objectList = new ArrayList<Map<String,Object>>();
 		if(vrtc.getMtObjId().equals(MtObjTypeEnum.CONTACT.getValue())){
			// 查询关联联系人任务卡详情
 			objectList = getContactList(scheduleId, vrtc.getMtBiztypeId(), ScheduleTypeEnum.CUSVISIT.getValue());
		}else if(vrtc.getMtObjId().equals(MtObjTypeEnum.LEAD.getValue())){
			//TODO 查询关联线索任务卡详情
		}else if(vrtc.getMtObjId().equals(MtObjTypeEnum.OPPORTUNITY.getValue())){
			// 查询关联商机任务卡详情
			objectList = getopportunityList(scheduleId, vrtc.getMtBiztypeId(), ScheduleTypeEnum.CUSVISIT.getValue());
		}else if(vrtc.getMtObjId().equals(MtObjTypeEnum.COMPETITIVE.getValue())){
			//TODO 查询关联竞品采集任务卡详情
		}
 		if(objectList != null && objectList.size() > 0){
 			return "Y";
 		}
		return "N";
	}
	
	/**
	 * 根据方法名称取值
	 * @param obj
	 * @param funcName
	 * @return
	 */
	private int getValueByMethodName(Object obj, String funcName) {
		int res = -1;
		if (!funcName.equals("")) {
			try {
				Object value = obj.getClass().getMethod(funcName, new Class[]{}).invoke(obj, new Object[]{});
				if (value != null) {
					res = (int)value;
				}
			} catch (IllegalAccessException | IllegalArgumentException
					| InvocationTargetException | NoSuchMethodException
					| SecurityException e) {
				throw new CrmBusinessException("日程获取客户信息错误");
			}
		}
		return res;
	}

	/**
	 * 翻译负责人部门名称
	 * @param userList
	 * @return
	 */
	private List<UserVO> transUser(List<UserVO> userList) {
		if (userList != null && userList.size() > 0) {
			List<FieldRelation<UserVO>> relations = new ArrayList<FieldRelation<UserVO>>();
			relations.add(new RefFieldRelation<UserVO>(UserVO.class, "deptId", new String[]{"deptName"}, orgService, "selectFieldsByIds"));
			new FieldRelationHandler<UserVO>().handler(userList, relations);
		}

		return userList;
	}

	/**
	 * 获取公司拜访规则列表
	 * @param orgId
	 * @return
	 */
	private List<VisitruleVO> getVisitRuleList(String orgId) {
		Map<String, Object> paraMap = new HashMap<>();
//		paraMap.put("orgId", orgId);
		long refIndex = getRefIndex();
		paraMap.put("refIndex", refIndex);
		List<VisitruleVO> res = new ArrayList<>();
		res = visitruleService.getRefList(paraMap);
		return res;
	}

	/**
	 * 获取拜访规则类型设置
	 * @return
	 */
	public long getRefIndex(){
		//TODO获取拜访规则类型设置
		return 1;
	}
	
	/**
	 * 获取客户拜访任务卡完成列表
	 * @param id
	 * @param objType
	 * @param objBiztype
	 * @param scheduleType
	 * @return
	 */
	public List<Map<String, Object>> getCumVisitFinishedList(Long id, Long objType, Long objBiztype, String scheduleType){
		if(objType.equals(MtObjTypeEnum.CONTACT.getValue())){
			return getContactList(id, objBiztype, scheduleType);
		}else if(objType.equals(MtObjTypeEnum.LEAD.getValue())){
			return getLeadList(id, objBiztype, scheduleType);
		}else if(objType.equals(MtObjTypeEnum.OPPORTUNITY.getValue())){
			return getopportunityList(id, objBiztype, scheduleType);
		}else if(objType.equals(MtObjTypeEnum.COMPETITIVE.getValue())){
			return null;
		}else{
			return null;
		}
	}
	
	/**
	 * 获取商机列表
	 * @param scheduleId
	 * @param objBiztype
	 * @param scheduleType
	 * @return
	 */
	public List<Map<String, Object>> getopportunityList(Long scheduleId, Long objBiztype, Object scheduleType){
    	Map<String, Object> param = new HashMap<String, Object>();
		param.put("scheduleId", scheduleId);
		param.put("scheduleType", scheduleType);
		param.put("objBiztypeId", objBiztype);
		return dao.selectList(OpportunityVO.class, "getOpportunityList", param);
    }
	
	/**
	 * 获取联系人列表
	 * @param scheduleId
	 * @param objBiztype
	 * @param scheduleType
	 * @return
	 */
	public List<Map<String, Object>> getContactList(Long scheduleId, Long objBiztype, Object scheduleType){
    	Map<String, Object> param = new HashMap<String, Object>();
		param.put("scheduleId", scheduleId);
		param.put("scheduleType", scheduleType);
		param.put("objBiztypeId", objBiztype);
		return dao.selectList(ContactVO.class, "getContactList", param);
    }
	
	/**
	 * 获取线索列表
	 * @param scheduleId
	 * @param objBiztype
	 * @param scheduleType
	 * @return
	 */
	public List<Map<String, Object>> getLeadList(Long scheduleId, Long objBiztype, Object scheduleType){
    	Map<String, Object> param = new HashMap<String, Object>();
		param.put("scheduleId", scheduleId);
		param.put("scheduleType", scheduleType);
		param.put("objBiztypeId", objBiztype);
		return dao.selectList(LeadVO.class, "getLeadList", param);
    }
	
}
